package cn.wawi.common.shiro;

import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import cn.wawi.dao.sys.ResourcesDao;
import cn.wawi.dao.sys.RoleDao;
import cn.wawi.dao.sys.UserDao;
import cn.wawi.entity.sys.Resources;
import cn.wawi.entity.sys.Role;
import cn.wawi.entity.sys.User;

public class CustomRealm extends AuthorizingRealm{

	@Resource
	protected UserDao<User> userDao;
	@Resource
	protected ResourcesDao<Resources> resourcesDao;
	@Resource
	protected RoleDao<Role> roleDao;
	// 设置realm的名称
	@Override
	public void setName(String name) {
		super.setName("customRealm");
	}
	public static void main(String[] args) {
		System.out.println(new Md5Hash("123456","admin",2).toString());
	}
	// 用于授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		  // 因为非正常退出，即没有显式调用 SecurityUtils.getSubject().logout()
        // (可能是关闭浏览器，或超时)，但此时缓存依旧存在(principals)，所以会自己跑到授权方法里。
        if (!SecurityUtils.getSubject().isAuthenticated()) {
            doClearCache(principals);
            SecurityUtils.getSubject().logout();
            return null;
        }
		User user=(User) principals.getPrimaryPrincipal();
		//单独定一个集合对象 
		List<String> permissions = new ArrayList<String>();
		List<String> role = new ArrayList<String>();
		List<Resources> privileges=resourcesDao.getUserPermission(user.getId(),2);
		if(privileges!=null){
			for(Resources p:privileges){
				//将数据库中的权限标签 符放入集合
				permissions.add(p.getPermCode());
			}
		}
		List<Role> roles=roleDao.getUserRole(user.getId());
		if(roles!=null){
			for(Role r:roles){
				//将数据库中的权限标签 符放入集合
				role.add(r.getRoleCode());
			}
		}
		//查到权限数据，返回授权信息(要包括 上边的permissions)
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		//将上边查询到授权信息填充到simpleAuthorizationInfo对象中
		simpleAuthorizationInfo.addStringPermissions(permissions);
		simpleAuthorizationInfo.addRoles(role);
		return simpleAuthorizationInfo;
	}
	//realm的认证方法
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String username=(String) token.getPrincipal();
		User user=new User(username);
		user=userDao.findOne(user);
		//账号不存在
		if(user==null){
			 throw new UnknownAccountException("账号不存在!");
		}
        //帐号已被锁定
        if("0".equals(user.getStatus())) {
            throw new DisabledAccountException("帐号已被禁用!");
        }
		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
				user, user.getPassword(),ByteSource.Util.bytes(username), this.getName());
		return simpleAuthenticationInfo;
	}
	
	//清除缓存
	public void clearCached() {
		PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
		super.clearCache(principals);
	}
	
}
